#include "process.h"

int Process::numberObject = 0;

Process::Process(int argc, char *argv[])
{
#ifdef USE_OPENMP
#pragma omp threadprivate(rank)
#pragma omp threadprivate(next)
#pragma omp threadprivate(root)

#pragma omp parallel
{
    rank = omp_get_thread_num();
    size = omp_get_num_threads();
}
#elif USE_MPI
    if (numberObject == 0) {
        int init;
        MPI_Initialized(&init);
        if (!init)
            MPI_Init(&argc, &argv);
    }
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
#elif USE_SHMEM
    if (numberObject == 0)
        shmem_init(&argc, &argv);
    rank = shmem_my_pe();
    size = shmem_n_pes();
#endif
    numberObject++;
    root = NUMBER_OF_ROOT;
}

Process::~Process()
{
    numberObject--;
    if (numberObject == 0)
#ifdef USE_OPENMP
        ;
#elif USE_MPI
        MPI_Finalize();
#elif USE_SHMEM
        shmem_finalize();
#endif
}


int Process::getRank()
{
    return rank;
}

int Process::getSize()
{
    return size;
}

void Process::barrierAll()
{
#ifdef USE_OPENMP
#pragma omp barrier
#elif USE_MPI
    MPI_Barrier(MPI_COMM_WORLD);
#elif USE_SHMEM
    shmem_barrier_all();
#endif
}

double Process::getTime()
{
    double time;
#ifdef USE_OPENMP
    time = omp_get_wtime();
#elif USE_MPI
    time = MPI_Wtime();
#elif USE_SHMEM
    time = shmem_time();
#endif
    return time;
}
